#include <utillib/memory/protect.h>
#include <windows.h>

using namespace utillib::memory;

Protect::ClassGuard::ClassGuard( Protect *buffer ) : m_buffer( buffer )
{
	m_buffer->enable();
}
Protect::ClassGuard::~ClassGuard()
{
	m_buffer->disable();
}

Protect::Protect( size_t size )
{
	m_size = size;
}

Protect::~Protect()
{
}

void * Protect::operator new ( size_t size )
{
	Protect *protect = ( Protect* )VirtualAlloc( 0, size, MEM_COMMIT, PAGE_READWRITE );
	return protect;
}

void Protect::operator delete ( void *buffer )
{
	VirtualFree( buffer, ( ( Protect * )buffer)->m_size, MEM_DECOMMIT );
}


bool Protect::disable()
{
	DWORD dw;
	if ( VirtualProtect( ( void *)this, m_size, PAGE_READONLY, &dw ) == TRUE ) return ( true );
	return ( false );
}

bool Protect::enable()
{
	DWORD dw;
	if ( VirtualProtect( ( void *)this, m_size, PAGE_READWRITE, &dw ) == TRUE ) return ( true );
	return ( false );
}

Protect::GuardMemory *Protect::guardMemoryAlloc( int size )
{
	GuardMemory *buffer = new GuardMemory;
	if ( buffer == NULL ) return ( NULL );

	buffer->size = size;
	buffer->buffer = VirtualAlloc( 0, size, MEM_COMMIT, PAGE_READWRITE );
	if ( buffer->buffer == NULL ) return ( NULL );
	DWORD dw = 0;
	VirtualProtect( ( void *)buffer->buffer, buffer->size, PAGE_READONLY, &dw );
	return ( buffer );

}

void Protect::guardMemoryFree( Protect::GuardMemory **buffer )
{
	VirtualFree( ( *buffer )->buffer , ( *buffer )->size, MEM_DECOMMIT );
	SAFE_DELETE( *buffer );

}

Protect::MemoryGuard::MemoryGuard( GuardMemory *buffer ) : m_buffer( buffer )
{
	DWORD dw = 0;
	VirtualProtect( ( void *)m_buffer->buffer, m_buffer->size, PAGE_READWRITE, &dw );
}

Protect::MemoryGuard::~MemoryGuard()
{
	DWORD dw = 0;
	VirtualProtect( ( void *)m_buffer->buffer, m_buffer->size, PAGE_READONLY, &dw );
}
